[归档] dynamic-thread-pool动态线程池管理插件
说明*
开源的DynamicTp动态线程池实现功能更强大完善,此插件停止维护。
实现原理
原理可参考Java线程池实现原理及其在美团业务中的实践。
快速上手
1. Maven依赖
在项目的 pom.xml
中添加以下依赖:
<parent>
<groupId>com.yupaits</groupId>
<artifactId>yutool-parent</artifactId>
<version>${yutool.version}</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>com.yupaits</groupId>
<artifactId>dynamic-thread-pool</artifactId>
</dependency>
</dependencies>
2
3
4
5
6
7
8
9
10
11
12
13
2. 配置类
编写AbstractDynamicThreadPoolManager
的子类并使用@Component
注解标识为Spring Bean,并实现getAppId()
方法,该方法用于获取当前应用的appId
。
@Component
public class DynamicThreadPoolManager extends AbstractDynamicThreadPoolManager {
@Value("${spring.application.name}")
private String appId;
@Override
public String getAppId() {
return appId;
}
}
2
3
4
5
6
7
8
9
10
11
实现ExecutorConfigFetcher
接口并使用@Component
注解标识为Spring Bean,该接口用于根据appId
及poolName
动态获取线程池配置。配置信息的数据源可以是数据库、配置中心等。
@Component
public class DbExecutorConfigFetcher implements ExecutorConfigFetcher {
@Override
public List<ExecutorProps> fetchAllConfig(String appId) {
// 从数据库中查询获取配置
...
}
@Override
public Map<String, ExecutorProps> fetchConfigList(String appId, Collection<String> poolNames) {
// 从数据库中查询获取配置
...
}
@Override
public ExecutorProps fetchConfig(String appId, String poolName) {
// 从数据库中查询获取配置
...
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
在分布式系统中使用
当我们在分布式系统中使用动态线程池时,如果同一个线程池配置被多个应用同时使用,而在其中一个应用修改线程池配置时,往往需要将配置同步更新至其他应用。插件中使用了ExecutorPublisher
和ExecutorConfigListener
接口抽象了同步更新至其他应用这一行为。
插件中的CallbackApiListener
实现了ExecutorConfigListener
接口,它是通过回调接口的方式接收通知用于更新当前应用的线程池配置,该方式适用于一个appId
只有一个部署实例的场景。
实现CallbackUrlFetcher
接口并使用@Component
注解标识为Spring Bean,该接口用于根据appId
获取目标应用的回调接口地址,当动态线程池的配置发生变更(新增、删除、修改)时,调用该回调接口通知目标应用进行相应的变更。
@Component
public class DynamicThreadPoolCallbackUrlFetcher implements CallbackUrlFetcher {
@Override
public String fetchUrl(String appId) {
return getAppIp(appId) + "/executor/config/callback";
}
private String getAppId(String appId) {
// 根据appId获取ip
String ip = ...;
return ip;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
而当我们的系统更加复杂,例如同一个appId
(服务)下部署了多个实例时,则还需要获取该appId
下的所有实例(可以通过注册中心的相关api获取),并向所有实例发送更新通知,此时推荐使用消息中间件的多对一消费
模式来实现。
评论区留言准则:
1. 本评论区禁止传播封建迷信、吸烟酗酒、低俗色情、赌博诈骗等任何违法违规内容。
2. 当他人以不正当方式诱导打赏、私下交易,请谨慎判断,以防人身财产损失。
3. 请勿轻信各类招聘征婚、代练代抽、私下交易、购买礼包码、游戏币等广告信息,谨防网络诈骗。